#[钛妹]: 钛哥！外卖满减计算总写重复代码，能封装吗？
#[钛哥]: 这就该函数登场了！先看个基础款：
def calculate_discount(total):
    """计算满100减20优惠"""
    return total - 20 if total >= 100 else total

print("实付金额:", calculate_discount(150))  # 130

#[钛妹]: 参数能多个吗？比如新用户加折扣？
#[钛哥]: 多参数走起！注意位置顺序：
def user_discount(total, is_new):
    discount = 20 if total >=100 else 0
    return total - discount - (10 if is_new else 0)

print("新用户优惠:", user_discount(90, True))  # 80

#[钛妹]: 参数顺序记混怎么办？
#[钛哥]: 关键字参数来救场！顺序自由：
print(user_discount(is_new=True, total=200))  # 170

#[钛妹]: 参数默认值怎么设？比如会员等级
#[钛哥]: 默认参数超方便！但要注意陷阱：
def vip_discount(total, level=1):
    rates = {1:0.9, 2:0.8, 3:0.7}
    return total * rates.get(level, 1)

print("白金会员:", vip_discount(100,3))  # 70
print("默认会员:", vip_discount(100))    # 90

#[钛妹]: 星号参数是干嘛的？像*args这种
#[钛哥]: 打包任意数量参数！看商品折扣：
def multi_discount(*prices):
    return sum(prices) * 0.8

print("多商品折扣:", multi_discount(30,50,20))  # 80

#[钛妹]: 双星号又是什么黑科技？
#[钛哥]: 收快递式收参数！键值对打包：
def address_printer(**info):
    print(f"{info['name']}收，电话{info['phone']}")

address_printer(name="钛妹", phone="13800138000")

#[钛妹]: 参数还能强制指定类型？
#[钛哥]: 类型注解安排！Python3.5+支持：
def type_checked(a:int, b:float) -> float:
    return a + b

print("类型检查结果:", type_checked(3, 5.5))  # 8.5

#[钛妹]: 函数返回多个值怎么办？
#[钛哥]: 元组打包，解包接收！看实例：
def multi_return():
    return "苹果", 6, 12.5

fruit, qty, price = multi_return()
print(f"{fruit}单价{price}，买{qty}斤")

#[钛妹]: 递归是什么魔法？能展示吗？
#[钛哥]: 自调用函数！注意终止条件：
def factorial(n):
    return 1 if n == 0 else n * factorial(n-1)

print("5的阶乘:", factorial(5))  # 120

#[钛妹]: 函数还能嵌套？里函数能调用吗？
#[钛哥]: 闭包来也！看这个计数器：
def counter():
    count = 0
    def inner():
        nonlocal count
        count +=1
        return count
    return inner

c = counter()
print(c(), c(), c())  # 1 2 3

#[钛妹]: 装饰器是什么高级玩法？
#[钛哥]: 不修改原函数添加功能！看：
def logger(func):
    def wrapper(*args):
        print(f"正在执行{func.__name__}")
        return func(*args)
    return wrapper

@logger
def add(a,b):
    return a + b

print(add(3,5))  # 先打印日志再输出8

#[钛妹]: 参数还能限制类型？比如仅位置
#[钛哥]: 新语法！/前是仅位置，*后是仅关键字
def special_args(a, b, /, c, *, d):
    print(f"a={a}, d={d}")

special_args(1,2,c=3,d=4)  # 正确
# special_args(a=1,b=2,c=3,d=4)  # 报错

#[钛妹]: lambda和普通函数怎么选？
#[钛哥]: 对比实验见分晓：
import timeit

def square_def(x): return x*x
square_lambda = lambda x: x*x

print("def耗时:", timeit.timeit('square_def(5)', globals=globals()))
print("lambda耗时:", timeit.timeit('square_lambda(5)', globals=globals()))

#[钛妹]: 函数变量作用域有什么讲究？
#[钛哥]: LEGB规则！看这个实验：
x = "全局变量"
def scope_test():
    x = "局部变量"
    print("内部:", x)

scope_test()  # 局部变量
print("外部:", x)  # 全局变量

#[钛妹]: 函数还能修改外部变量？
#[钛哥]: global声明安排！谨慎使用：
def global_mod():
    global x
    x = "被修改的全局变量"

global_mod()
print("修改后:", x)  # 被修改的全局变量

#[钛妹]: 递归处理树结构方便吗？
#[钛哥]: 文件树遍历示范：
def walk_directory(path, depth=0):
    import os
    print("  "*depth + os.path.basename(path))
    if os.path.isdir(path):
        for item in os.listdir(path):
            walk_directory(os.path.join(path,item), depth+1)

walk_directory("..") 

#[钛妹]: 总结今日所学：
# 1. 函数是代码复用利器
# 2. 参数花样玩出业务逻辑
# 3. 装饰器是功能增强神器
# 4. 递归优雅但要注意终止
#[钛哥]: 漏了重要一点！
# 5. 合理使用作用域避免冲突

#[钛妹]: 对了各位！持续学习才是硬道理！点赞关注不迷路！